package com.duowan.cms.parser;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.duowan.cms.common.domain.Page;
import com.duowan.cms.common.dto.SearchCriteria;
import com.duowan.cms.common.exception.BaseCheckedException;
import com.duowan.cms.common.util.StringUtil;
import com.duowan.cms.common.util.ThreadUtil;
import com.duowan.cms.core.rmi.client.article.ArticleRemoteService;
import com.duowan.cms.core.rmi.client.channel.ChannelRemoteService;
import com.duowan.cms.core.rmi.client.tag.TagRemoteService;
import com.duowan.cms.core.rmi.client.template.TemplateRemoteService;
import com.duowan.cms.dto.article.ArticleInfo;
import com.duowan.cms.dto.article.ArticleSearchCriteria;
import com.duowan.cms.dto.article.ArticleStatus;
import com.duowan.cms.dto.tag.TagInfo;
import com.duowan.cms.dto.template.TemplateInfo;
import com.duowan.cms.dto.template.TemplateSearchCriteria;
import com.duowan.cms.parser.rmi.client.template.TemplateBatchParserRemoteService;

@Service("templateBatchParserRemoteService")
public class TemplateBatchParserServiceImpl implements TemplateBatchParserService, TemplateBatchParserRemoteService {

    private static Logger logger = Logger.getLogger(TemplateBatchParserService.class);

    @Autowired
    private TagRemoteService tagRemoteService;

    @Autowired
    private ChannelRemoteService channelRemoteService;

    @Autowired
    private TemplateRemoteService templateRemoteService;

    @Autowired
    private ArticleRemoteService articleRemoteService;

    @Autowired
    private TemplateParserService templateParserService;

    @Override
    public void flushOneTagInChannel(final String channelId, final String tagName) {
        final TagInfo tagInfo = tagRemoteService.getByChannelIdAndName(channelId, tagName);
        try {
            templateParserService.parseTagAndGenerateFile(channelRemoteService.getById(channelId), tagInfo);
        } catch (BaseCheckedException e) {
            logger.error("解析标签[" + tagInfo.getName() + "]出错，原因：" + e.getMessage());
        }
    }

    @Override
    public void flushAllTagInChannel(final String channelId) {
        logger.info("开始刷新"+channelId+"频道的tag全刷新");
        List<TagInfo> infos = tagRemoteService.getAllTagsInChannel(channelId);
        for (final TagInfo tagInfo : infos) {
            try {
                templateParserService.parseTagAndGenerateFile(channelRemoteService.getById(channelId), tagInfo);
            } catch (BaseCheckedException e) {
                logger.error("解析标签[" + tagInfo.getName() + "]出错，原因：" + e.getMessage());
            }
        }
        logger.info("结束刷新"+channelId+"频道的tag全刷新");
    }

    @Override
    public void flushAllTemplateInChannnel(final String channelId) {
        if (StringUtil.isEmpty(channelId))
            return;
        logger.info("开始刷新" + channelId + "频道下的所有模板");
        int pageSize = 200;
        int pageNo = 1;
        TemplateSearchCriteria searchCriteria = new TemplateSearchCriteria();
        searchCriteria.setChannelId(channelId);
        searchCriteria.setPageNo(pageNo);
        searchCriteria.setPageSize(pageSize);
        while (true) {
            final Page<TemplateInfo> templateInfoPage = templateRemoteService.pageSearch(searchCriteria);
            if (templateInfoPage != null && !templateInfoPage.getResult().isEmpty()) {
                ThreadUtil.getThreadPool().execute(new Runnable() {
                    public void run() {
                        List<TemplateInfo> templateInfos = templateInfoPage.getResult();
                        for (int i = 0; i < templateInfos.size(); i++) {
                            try {
                                templateParserService.parseTemplateAndGenerateFile(channelRemoteService.getById(channelId), templateInfos.get(i));
                            } catch (BaseCheckedException e) {
                                logger.error("解析模板[" + templateInfos.get(i).getId() + "]出错，原因：" + e.getMessage());
                            }
                        }
                    }
                });
            } else {
                break;
            }

            searchCriteria.setPageNo(pageNo++);
        }
    }

    @Override
    public void flushAllArticleInChannelId(final String channelId) {
        fulshArticleBySearchCriteria(channelId, this.getBaseSeachCriteria(channelId));
    }

    @Override
    public void flushArticleInChannelByDate(String channelId, Date beginTime, Date endTime) {
        // TODO Auto-generated method stub

    }

    @Override
    public void flushArticleInChannelByTag(String channelId) {
        // TODO Auto-generated method stub

    }

    @Override
    public void flushArticleAfterDateInChannelId(final String channelId, Date date) {
        ArticleSearchCriteria criteria = this.getBaseSeachCriteria(channelId);
        if(date!=null){
            criteria.setPublishTimeStart(date);
        }
        fulshArticleBySearchCriteria(channelId, criteria);
    }

    @Override
    public void flushArticleByTagInChannelId(String channelId, String tag) {
        ArticleSearchCriteria criteria = this.getBaseSeachCriteria(channelId);
        if(!StringUtil.isEmpty(tag)){
            criteria.addTags(tag);
        }
        fulshArticleBySearchCriteria(channelId, criteria);
    }
    
    
    private ArticleSearchCriteria getBaseSeachCriteria(String channelId){
        int pageSize = 200;
        int pageNo = 1;
        ArticleSearchCriteria criteria = new ArticleSearchCriteria();
        //criteria.addStatus(ArticleStatus.CATCHED);
        //criteria.addStatus(ArticleStatus.NO_TAG);
        criteria.addStatus(ArticleStatus.NORMAL);
        criteria.setChannelId(channelId);
        criteria.setPageNo(pageNo);
        criteria.setPageSize(pageSize);
        return criteria; 
    }
    
    private void fulshArticleBySearchCriteria(final String channelId, final ArticleSearchCriteria criteria){
        while (true) {
            final List<ArticleInfo> page = articleRemoteService.listSearch(criteria);
            if (page != null && !page.isEmpty()) {
                ThreadUtil.getThreadPool().execute(new Runnable() {
                    public void run() {
                        //List<ArticleInfo> articleInfos = page.getResult();
                        for (final ArticleInfo articleInfo : page) {
                            try {
                                templateParserService.parseArticleAndGenerateFile(channelRemoteService.getById(channelId), articleInfo);
                            } catch (BaseCheckedException e) {
                                logger.error("解析文章[" + articleInfo.getId() + "]出错，原因：" + e.getMessage());
                            }
                        }
                    }
                });
            } else {
                break;
            }
            criteria.setPageNo(criteria.getPageNo()+1);
        }
    }
    
    @Override
    public void flushByArticleTemplateId(String channelId, String templateId) {
        ArticleSearchCriteria criteria = this.getBaseSeachCriteria(channelId);
        criteria.setTemplateId(Long.parseLong(templateId));
        fulshArticleBySearchCriteria(channelId, criteria);
    }

}
